#!/usr/bin/env python
# -*- coding: utf-8 -*-

import re
import sys
import lib
_LOG = False


def catch_str(strval, p1='', p2='', dtype=str):
    '''
    ^.*p1{content}p2
    '''
    r = re.compile(r'^.*' + p1 + r'\s*([\d\.:]+)\s*' + p2, re.M | re.I)
    res = r.findall(strval)
    if len(res):
        if dtype == float:
            return float(res[0])
        elif dtype == int:
            return int(res[0])
        else:
            return res[0]  # str
    else:
        return None


def parse_file(filename: str, display_name=None):
    ret = {'file': display_name if display_name else filename}
    with open(filename, 'r', encoding='utf-8') as f:
        try:
            if _LOG:
                print("[parse]", filename)
            s = ''
            while True:
                s = f.readline()
                if s.startswith('[time]'):
                    break
                elif not s:
                    raise StopIteration
                pass

            # [time] ...
            ret['time_all'] = catch_str(s, 'all', dtype=float)
            ret['time_mit'] = catch_str(s, 'mithril', dtype=float)
            # [lru|opt] ..
            s = f.readline()
            ret['hr'] = catch_str(s, 'hit:?', '\(', dtype=float)
            if s.startswith('[lru]'):
                ret['pr'] = catch_str(s, 'eff', '\(', dtype=float)
                while True:
                    s = f.readline()
                    if s.startswith('[mithril] time'):
                        # get actual mithril time
                        t1 = catch_str(s, 'record', dtype=float)
                        t2 = catch_str(s, 'mining', dtype=float)
                        t3 = catch_str(s, 'prefetch', dtype=float)
                        ret['time_mit_real'] = round(t1 + t2 + t3 / 10, 8)  # or just t1+t2
                        break
                    elif len(s) == 0:
                        break
            pass
        except StopIteration:
            if _LOG:
                print('@[EOF]')
        finally:
            f.close()
    return ret


def get_headers(data: dict) -> 'list[str]':
    ret = []
    for it in data:
        for k in it:
            if k not in ret:
                ret.append(k)
    return ret


def parse_dir(dirname: str, file_pat='.*', dir_pat='.*'):
    print('@[%s] "%s" "%s"' % (dirname, file_pat, dir_pat))
    files = lib.recursion_dir(dirname, file_pat, dir_pat)
    files.sort()
    print(files)
    data = [parse_file(fn, fn.replace(dirname, '')) for fn in files]
    print(data)

    if len(data) > 0:
        headers = get_headers(data)
        print('\n{')
        for k in headers:
            print("  '%s':" % k, [x[k] if (k in x) else None for x in data], ',')
        print('}')
    pass


if __name__ == '__main__':
    if len(sys.argv) > 1:
        parse_dir(*sys.argv[1:])
    else:
        print("extdir.py <dir> [file pattern='.*'] [dir pattern='.*']")
